package fox.framework.rpc.endpoint.netty.server;

import fox.framework.rpc.common.WebUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.util.Collection;


/********************************************
 * protocol status\n
 * headerKey:value;\n
 * byteBody
 *******************************************/

/**
 * @author cuichao
 * @Description: FoxServerResponseEncode
 * @Date: create in 2021/1/19 23:03
 */
public class FoxServerResponseEncode extends MessageToByteEncoder<RpcEncodeServerResponse> {

    private static final String PROTOCOL_NAME = "fox";
    private static final String PROTOCOL_SPILT = "\n";
    private static final String PROTOCOL_ENTRY_SPILT = " ";
    private static final String HEADER_ENTRY_SPILT = ";";
    private static final String HEADER_KV_SPILT = ":";


    @Override
    protected void encode(ChannelHandlerContext ctx, RpcEncodeServerResponse response, ByteBuf out) throws Exception {
        String protocol = response.getProtocol();
        if (!PROTOCOL_NAME.equals(protocol)) {
            ctx.write(response);
            return;
        }
        /**
         * encode protocol
         */
        int status = response.getStatus();
        String protocol_line = String.format("%s %s", protocol, status) + PROTOCOL_SPILT;
        /**
         * encode header
         */
        Collection<String> headerNames = response.getHeaderNames();
        StringBuilder headerLineBuilder = new StringBuilder();
        for (String headerName : headerNames) {
            headerLineBuilder.append(String.format("%s:%s;", headerName, WebUtils.urlEncode(response.getHeader(headerName))));
        }
        headerLineBuilder.append(PROTOCOL_SPILT);
        String header_line = headerLineBuilder.toString();
        /**
         * write response
         */
        byte[] source = response.getBodySource();
        out.writeBytes(protocol_line.getBytes());
        out.writeBytes(header_line.getBytes());
        out.writeBytes(source);
    }
}
